/*
 * Toedo
 * Copyright (C) 2009-2010 J. Devauchelle and contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 3 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package org.toedo.controllers;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.commands.ActionHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.handlers.IHandlerService;
import org.toedo.gui.actions.NewNoteAction;
import org.toedo.gui.actions.NewProjectAction;
import org.toedo.gui.actions.NewTaskAction;
import org.toedo.gui.actions.OpenProjectAction;
import org.toedo.gui.actions.SaveProjectAction;
import org.toedo.gui.dialogs.TagsManagementDialog;
import org.toedo.gui.perspectives.MainPerspective;
import org.toedo.gui.translations.Messages;
import org.toedo.gui.views.BaseNoteViewPart;
import org.toedo.gui.views.DashboardView;
import org.toedo.gui.views.DebugView;
import org.toedo.gui.views.WikiFormatingView;
import org.toedo.gui.views.NotesListView;
import org.toedo.gui.views.ProjectPropertiesView;
import org.toedo.gui.views.TaskListView;
import org.toedo.logging.Log;
import org.toedo.utils.ApplicationUtils;
import org.toedo.Activator;
import org.toedo.ApplicationActionBarAdvisor;

public class MenuController {
	
	private IAction mNewAction;
	private IAction mOpenAction;
	private IAction mSaveAction;
	private IAction mSaveAsAction;
	//private IAction mExportHtmlAction;
	private IWorkbenchAction mExitAction;
	
	private IAction mAddTaskAction;
	private IAction mAddNoteAction;
	private IAction mManageTagsAction;
	
	private IAction mCutAction;
	private IAction mCopyAction;
	private IAction mPasteAction;
	private IAction mSwitchEditModeAction;
	private IAction mShowPreferenceAction;
	
	private IAction mShowProjectPropertiesAction;
	private IAction mShowDashboardAction;
	private IAction mShowTasksListAction;
	private IAction mShowNotesListAction;
	
	private IAction mShowWikiFormatingAction;
	private IAction mShowDebugAction;
	private IAction mResetViewsAction;
	private IAction mShowAboutAction;
	
	/**
	 * Holder for singleton implementation.
	 */
	private static class MenuControllerHolder {
		private static final MenuController INSTANCE = new MenuController();
	}
	
	/**
	 * Get the unique instance of the TrayController.
	 * @return The instance of the TrayController
	 */
	public static MenuController getInstance() {
		return MenuControllerHolder.INSTANCE;
	}

	private MenuController() {
		
	}
	
	private void buildFileActions(final IWorkbenchWindow window, IHandlerService handlerService) {
		mNewAction = new Action(Messages.ApplicationActionBarAdvisor_NewProjectAction, SWT.NONE) {
			public void run() {
				new NewProjectAction(Display.getCurrent().getActiveShell()).run();
			}
		};
		mNewAction.setImageDescriptor(Activator.getImageDescriptor("/icons/new-16.png")); //$NON-NLS-1$
		
		mOpenAction = new Action(Messages.ApplicationActionBarAdvisor_OpenProjectAction, SWT.NONE) {
			public void run() {
				new OpenProjectAction().run();
			}
		};
		mOpenAction.setActionDefinitionId("toedo-core.OpenProjectAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.OpenProjectAction", new ActionHandler(mOpenAction)); //$NON-NLS-1$
		
		mSaveAction = new Action(Messages.ApplicationActionBarAdvisor_SaveProjectAction, SWT.NONE) {
			public void run() {
				new SaveProjectAction(false).run();
			}
		};
		mSaveAction.setImageDescriptor(Activator.getImageDescriptor("/icons/save-16.png")); //$NON-NLS-1$
		mSaveAction.setActionDefinitionId("toedo-core.SaveProjectAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.SaveProjectAction", new ActionHandler(mSaveAction)); //$NON-NLS-1$

		mSaveAsAction = new Action(Messages.ApplicationActionBarAdvisor_SaveProjectAsAction, SWT.NONE) {
			public void run() {				
				new SaveProjectAction(true).run();
			}
		};
		
		/*
		mExportHtmlAction = new Action(Messages.MenuController_ExportToHtml, SWT.NONE) {
			public void run() {				
				new ExportToHtmlAction(Display.getCurrent().getActiveShell()).run();
			}
		};
		*/
		
		mExitAction = ActionFactory.QUIT.create(window);
	}
	
	private void fillFileMenu(IMenuManager menuBar) {
		MenuManager fileMenu = new MenuManager(Messages.MenuController_FileMenuItem);
		menuBar.add(fileMenu);
		
		fileMenu.add(mNewAction);		
		fileMenu.add(mOpenAction);
		fileMenu.add(new Separator());
		fileMenu.add(mSaveAction);
		fileMenu.add(mSaveAsAction);
		//fileMenu.add(new Separator());
		//fileMenu.add(mExportHtmlAction);
		fileMenu.add(new Separator());
		fileMenu.add(mExitAction);
	}
	
	private void buildEditActions(final IWorkbenchWindow window, IHandlerService handlerService) {
		mCutAction = ActionFactory.CUT.create(window);
		mCutAction.setAccelerator(SWT.CTRL + 'X');
		
		mCopyAction = ActionFactory.COPY.create(window);
		mCopyAction.setAccelerator(SWT.CTRL + 'C');
		
		mPasteAction = ActionFactory.PASTE.create(window);
		mPasteAction.setAccelerator(SWT.CTRL + 'V');
		
		mSwitchEditModeAction = new Action(Messages.MenuController_SwithEditMode, SWT.CHECK) {
			public void run() {
				IWorkbenchPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart(); 
				if (part instanceof BaseNoteViewPart) {
					((BaseNoteViewPart) part).switchEditMode();
				}
			}
		};
		mSwitchEditModeAction.setId("toedo-core.SwitchEditModeAction"); //$NON-NLS-1$
		mSwitchEditModeAction.setImageDescriptor(Activator.getImageDescriptor("/icons/edit-16.png")); //$NON-NLS-1$
		mSwitchEditModeAction.setActionDefinitionId("toedo-core.SwitchEditModeAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.SwitchEditModeAction", new ActionHandler(mSwitchEditModeAction)); //$NON-NLS-1$
		mSwitchEditModeAction.setEnabled(false);
				
		mShowPreferenceAction = ActionFactory.PREFERENCES.create(window);
	}
	
	private void fillEditMenu(IMenuManager menuBar) {
		MenuManager editMenu = new MenuManager(Messages.MenuController_Edit);
		menuBar.add(editMenu);
		
		editMenu.add(mCutAction);
		editMenu.add(mCopyAction);
		editMenu.add(mPasteAction);
		editMenu.add(new Separator());
		editMenu.add(mSwitchEditModeAction);
		editMenu.add(new Separator());
		editMenu.add(mShowPreferenceAction);
	}
	
	private void buildActionsActions(final IWorkbenchWindow window, IHandlerService handlerService) {
		mAddTaskAction = new Action(Messages.MenuController_NewTaskAction, SWT.NONE) {
			public void run() {
				new NewTaskAction(Display.getCurrent().getActiveShell(), true).run();
			}
		};
		mAddTaskAction.setImageDescriptor(Activator.getImageDescriptor("/icons/newtask-16.png")); //$NON-NLS-1$
		mAddTaskAction.setActionDefinitionId("toedo-core.NewTaskAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.NewTaskAction", new ActionHandler(mAddTaskAction)); //$NON-NLS-1$
		
		mAddNoteAction = new Action(Messages.MenuController_NewNote, SWT.NONE) {
			public void run() {
				new NewNoteAction(Display.getCurrent().getActiveShell(), true).run();
			}
		};
		mAddNoteAction.setImageDescriptor(Activator.getImageDescriptor("/icons/newnote-16.png")); //$NON-NLS-1$
		mAddNoteAction.setActionDefinitionId("toedo-core.NewNoteAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.NewNoteAction", new ActionHandler(mAddNoteAction)); //$NON-NLS-1$
		
		mManageTagsAction = new Action(Messages.MenuController_ManageTags, SWT.NONE) {
			public void run() {
				new TagsManagementDialog(Display.getCurrent().getActiveShell()).open();
			}
		};
		mManageTagsAction.setImageDescriptor(Activator.getImageDescriptor("/icons/tag-16.png")); //$NON-NLS-1$
	}
	
	private void fillActionsMenu(IMenuManager menuBar) {
		MenuManager actionsMenu = new MenuManager(Messages.MenuController_ActionMenuItem);
		menuBar.add(actionsMenu);
		
		actionsMenu.add(mAddTaskAction);
		actionsMenu.add(mAddNoteAction);
		actionsMenu.add(new Separator());
		actionsMenu.add(mManageTagsAction);
	}
	
	private void buildViewsActions(final IWorkbenchWindow window, IHandlerService handlerService) {
		mShowDashboardAction = new Action(Messages.MenuController_Dashboard, SWT.NONE) {
			public void run() {
				ApplicationUtils.showViewByID(DashboardView.ID);
			}
		};
		mShowDashboardAction.setImageDescriptor(Activator.getImageDescriptor("/icons/dashboard-16.png")); //$NON-NLS-1$
		mShowDashboardAction.setActionDefinitionId("toedo-core.OpenDashboardAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.OpenDashboardAction", new ActionHandler(mShowDashboardAction)); //$NON-NLS-1$
		
		mShowTasksListAction = new Action(Messages.MenuController_TasksList, SWT.NONE) {
			public void run() {
				ApplicationUtils.showViewByID(TaskListView.ID);
			}
		};
		mShowTasksListAction.setImageDescriptor(Activator.getImageDescriptor("/icons/tasklist-16.png")); //$NON-NLS-1$
		mShowTasksListAction.setActionDefinitionId("toedo-core.OpenTasksListAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.OpenTasksListAction", new ActionHandler(mShowTasksListAction)); //$NON-NLS-1$
		
		mShowNotesListAction = new Action(Messages.MenuController_ShowNotesList, SWT.NONE) {
			public void run() {
				ApplicationUtils.showViewByID(NotesListView.ID);
			}
		};
		mShowNotesListAction.setImageDescriptor(Activator.getImageDescriptor("/icons/notelist-16.png")); //$NON-NLS-1$
		mShowNotesListAction.setActionDefinitionId("toedo-core.OpenNotesListAction"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.OpenNotesListAction", new ActionHandler(mShowNotesListAction)); //$NON-NLS-1$
		
		mShowProjectPropertiesAction = new Action(Messages.ApplicationActionBarAdvisor_ShowProjectProperties, SWT.NONE) {
			public void run() {
				ApplicationUtils.showViewByID(ProjectPropertiesView.ID);
			}
		};
		mShowProjectPropertiesAction.setImageDescriptor(Activator.getImageDescriptor("/icons/projectproperties-16.png")); //$NON-NLS-1$
	}
	
	private void fillViewsMenu(IMenuManager menuBar) {
		MenuManager viewsMenu = new MenuManager(Messages.MenuController_ViewsMenuItem);
		menuBar.add(viewsMenu);
	
		viewsMenu.add(mShowDashboardAction);
		viewsMenu.add(mShowTasksListAction);
		viewsMenu.add(mShowNotesListAction);
		viewsMenu.add(new Separator());
		viewsMenu.add(mShowProjectPropertiesAction);
	}
	
	private void buildHelpActions(final IWorkbenchWindow window, IHandlerService handlerService) {
		mShowWikiFormatingAction = new Action(Messages.MenuController_WikiFormatingHelp, SWT.NONE) {
			public void run() {
				ApplicationUtils.switchViewVisibleStateById(WikiFormatingView.ID);
			}
		};
		mShowWikiFormatingAction.setImageDescriptor(Activator.getImageDescriptor("/icons/wikihelp-16.png")); //$NON-NLS-1$
		mShowWikiFormatingAction.setActionDefinitionId("toedo-core.SwitchWikiFormating"); //$NON-NLS-1$
		handlerService.activateHandler("toedo-core.SwitchWikiFormating", new ActionHandler(mShowWikiFormatingAction)); //$NON-NLS-1$
		
		mShowDebugAction = new Action(Messages.MenuController_ShowDebugView, SWT.NONE) {
			public void run() {
				ApplicationUtils.showViewByID(DebugView.ID);
			}
		};
		mShowDebugAction.setImageDescriptor(Activator.getImageDescriptor("/icons/debug-16.png")); //$NON-NLS-1$
		
		mResetViewsAction = new Action(Messages.MenuController_ResetViewsAction, SWT.NONE) {
			public void run() {
				try {
					PlatformUI.getWorkbench().showPerspective(MainPerspective.ID, window);
					PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().resetPerspective();
				} catch (WorkbenchException e) {
					Log.getInstance(ApplicationActionBarAdvisor.class).warn("Unable to reset UI: " + e.getMessage()); //$NON-NLS-1$
				}
			}
		};
		
		mShowAboutAction = ActionFactory.ABOUT.create(window);
	}
	
	private void fillHelpMenu(IMenuManager menuBar) {
		MenuManager helpMenu = new MenuManager(Messages.MenuController_HelpMenu);
		menuBar.add(helpMenu);
		
		helpMenu.add(mShowWikiFormatingAction);
		helpMenu.add(new Separator());
		helpMenu.add(mShowDebugAction);
		helpMenu.add(mResetViewsAction);
		helpMenu.add(new Separator());
		helpMenu.add(mShowAboutAction);
	}
	
	public void setSwitchEditActionEnabled(boolean value) {
		mSwitchEditModeAction.setEnabled(value);
	}
	
	public void makeActions(IWorkbenchWindow window, IHandlerService handlerService) {
		buildFileActions(window, handlerService);
		buildEditActions(window, handlerService);
		buildActionsActions(window, handlerService);
		buildViewsActions(window, handlerService);
		buildHelpActions(window, handlerService);
	}
	
	public void fillMenuBar(IMenuManager menuBar) {
    	fillFileMenu(menuBar);
    	fillEditMenu(menuBar);
		fillActionsMenu(menuBar);
		fillViewsMenu(menuBar);
		fillHelpMenu(menuBar);
    }
}
